Json = Json or require("common.Json")
local AbsActLogic = require("absAct.AbsActLogic")
local AbsActExcel = require("excel.absAct")
local buyExcel = require("excel.buy").buy
local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local AbsActDefine = require("absAct.AbsActDefine")
local YunYingLogic = require("yunying.YunYingLogic")
local PanelDefine = require("broadcast.PanelDefine")
local Util = require("common.Util")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local BuyLogic = require("topup.BuyLogic")

--[[
    absAct.xlsx-signGift
    情人节活动
        1、每天免费请求一次礼包
        2、购买专属浪漫签

    DB:
        human.db.absAct[id] = {
            [buyStatus] = xxx, -- 礼包购买状态
            [configId] = {
                signStatus = xxx    -- 签到状态 0未签到 1可签到 2已签到
                giftStatus = xxx,   -- 专属礼包签到状态 0未签到 1可签到 2已签到 
            }
        }
    local:
        wrapSignGiftNet()    -- 包装情人节数据
        getConfigIdBuyId()      -- 通过活动子id和buyID取得购买配置信息
    public: 
        getAndSendMsg()         -- 发送活动数据
        isRed()                 -- 红点提醒
        isActive()              -- 激活状态
        isOpen()                -- 活动开启
        getLeftTime()           -- 得到活动剩余时间
        signGift()              -- 购买当天专属礼包
]]


GIFT_STATE_0 = 0  -- 未签到
GIFT_STATE_1 = 1  -- 已签到
GIFT_STATE_2 = 2  -- 不可签到

SIGN_STATE_0 = 0  -- 未签到
SIGN_STATE_1 = 1  -- 已签到
SIGN_STATE_2 = 2  -- 不可签到

BUY_STATE_0 = 0 -- 未购买
BUY_STATE_1 = 1 -- 已购买

local buyIdToConfigIds = {}
local function getConfigIdBuyId(actId, buyId)
    if buyIdToConfigIds[actId] then
        return buyIdToConfigIds[actId][buyId]
    end

    buyIdToConfigIds[actId] = {}
    local signGiftConfig = AbsActExcel.signGift
    for id, buyInfo in ipairs(signGiftConfig) do
        if actId == buyInfo.actId then
            buyIdToConfigIds[actId][buyInfo.buyID] = id
        end
    end

    return buyIdToConfigIds[actId][buyId]
end

function isOpen(human, YYInfo, funcConfig)
    return AbsActLogic.isStarted(human, funcConfig.funcID)
end

function isActive(human, YYInfo, funcConfig)
    return not isOpen(human, YYInfo, funcConfig)
end

function getLeftTime(human, YInfo, funcConfig)
    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID)
    return state and endTime - os.time() or 0
end

function isRed(human, YYInfo, funcConfig)
    local funcID = funcConfig.funcID
    local state, endTime, starTime = AbsActLogic.isStarted(human, funcID)
    if not state then
        return
    end

    local absConfig = AbsActExcel.absActivity[funcID]
    local absAct = human.db.absAct[funcID]
    if not absAct then
        return true
    end

    local curDay = Util.diffDay(starTime) + 1
    for confID, conf in pairs(AbsActExcel.signGift) do
        if conf.day <= curDay then
            local absActDB = absAct[confID]
            if not absActDB then
                return true
            else
                if absActDB.signStatus == SIGN_STATE_0 then
                    return true
                end

                if absAct.buyStatus == BUY_STATE_1 and absActDB.giftStatus == SIGN_STATE_0 then
                    return true
                end
            end
        end
    end

    return false
end

local function wrapSignGiftNet(human, absAct, net, id, index, actInfo, day, region)
    absAct[index] = absAct[index] or {}
    net.id = id
    net.funcID = index
    net.day = actInfo.day
    local freeItemCnt = #actInfo.freeItem
    net.signItems[0] = freeItemCnt
    for i = 1, freeItemCnt do
        Grid.makeItem(net.signItems[i], actInfo.freeItem[i][1], actInfo.freeItem[i][2])
    end

    local giftItemCnt = #actInfo.giftItem
    net.giftItems[0] = giftItemCnt
    for i = 1, giftItemCnt do
        Grid.makeItem(net.giftItems[i], actInfo.giftItem[i][1], actInfo.giftItem[i][2])
    end

    if day >= actInfo.day then
        net.signStatus = absAct[index].signStatus or SIGN_STATE_0
        if absAct.buyStatus == BUY_STATE_1 then
            net.giftStatus = absAct[index].giftStatus or GIFT_STATE_0
        else
            net.giftStatus = absAct[index].giftStatus or GIFT_STATE_2
        end
    else
        net.signStatus = absAct[index].signStatus or SIGN_STATE_2
        net.giftStatus = absAct[index].giftStatus or GIFT_STATE_2
    end
end

function signGift(human, id, conf)
    local status = AbsActLogic.isStarted(human, id)
    local absConfig = AbsActExcel.absActivity[id]
    if not absConfig or not status then
        return
    end

    local absAct = human.db.absAct[id]
    if not absAct then
        return
    end

    local giftID = conf.args[1]
    local config = AbsActExcel.signGift[giftID]
    if not config then
        return
    end

    local absActDB = human.db.absAct[id]
    local signStatus = absActDB[giftID].signStatus
    if signStatus and signStatus ~= SIGN_STATE_1 then
        return
    end

    human.db.absAct[id].buyStatus = BUY_STATE_1
    Broadcast.sendErr(human, Lang.ITEM_BUY_SUCCESS)

    getAndSendMsg(human, id)

    YunYingLogic.sendBanner(human)
    YunYingLogic.updateIcon(YYInfo[id], human)
    YunYingLogic.sendGroupUpdate(YYInfo[id], human, absConfig.panelID)
end

function getAndSendMsg(human, id)
    local state,endTime, starTime = AbsActLogic.isStarted(human, id)
    if not state then
        return
    end

    local absAct = human.db.absAct[id]
    local curDay = Util.diffDay(starTime) + 1
    if curDay > 3 or curDay < 1 then
        return
    end

    local msgRet = Msg.gc.GC_ABS_SIGNGIFT_QUERY
    msgRet.buyStatus = absAct.buyStatus or BUY_STATE_0
    msgRet.curDay = curDay
    local buyID
    local len = 0
    for index, actInfo in pairs(AbsActExcel.signGift) do
        if not buyID and actInfo.buyID ~= 0 then
            buyID = actInfo.buyID
        end

        len = len + 1
        wrapSignGiftNet(human, absAct, msgRet.list[len], id, index, actInfo, curDay, human.region)
    end

    BuyLogic.fontBuyItem(human, msgRet.buyItem, buyID)
    msgRet.list[0] = len
    Msg.send(msgRet, human.fd)
end

--[[
    请求签到道具
]]
function getItem(human, id, funcID, type)
    local state, endTime, starTime = AbsActLogic.isStarted(human, id)
    if not state then return end

    local absConfig = AbsActExcel.absActivity[id]
    if not absConfig then
        return
    end

    local config = AbsActExcel.signGift[funcID]
    if not config then
        return
    end

    local curDay = Util.diffDay(starTime) + 1
    if curDay < config.day then
        return
    end

    local typeStr = type == 1 and "signStatus" or "giftStatus"
    local absAct = human.db.absAct[id]
    local actInfoDB = absAct[funcID]
    if type == 1 and actInfoDB.signStatus and actInfoDB.signStatus ~= SIGN_STATE_0 then
        return
    end

    if type == 2 and (absAct.buyStatus == BUY_STATE_0 or actInfoDB.giftStatus and actInfoDB.giftStatus ~= GIFT_STATE_0) then
        return
    end

    if type == 1 then
        human.db.absAct[id][funcID].signStatus = SIGN_STATE_1
        BagLogic.addItemList(human, config.freeItem, "abs_sign_reward")
    elseif type == 2 then
        human.db.absAct[id][funcID].giftStatus = GIFT_STATE_1
        BagLogic.addItemList(human, config.giftItem, "abs_sign_gift")
    end

    Broadcast.sendErr(human, Lang.ITEM_GET_SUCCESS)

    getAndSendMsg(human, id)
    YunYingLogic.sendBanner(human)
    YunYingLogic.updateIcon(YYInfo[id], human)
    YunYingLogic.sendGroupUpdate(YYInfo[id], human, absConfig.panelID)
end

function updateDaily(human, funcID)
    local state, endTime, starTime = AbsActLogic.isStarted(human, funcID)
    if not state then
        return
    end

    local absAct = human.db.absAct[funcID]
    if not absAct then
        return
    end

    local curDay = Util.diffDay(starTime) + 1
    for giftID, conf in pairs(AbsActExcel.signGift) do
        if conf.day == curDay then
            absAct[giftID].signStatus = SIGN_STATE_0
            if absAct.buyStatus == BUY_STATE_1 then
                absAct[giftID].giftStatus = SIGN_STATE_0
            end
        end
    end

end